#pragma once
#include <string>
#include <memory>
#include <map>
#include <set>

class Token {
protected:
    const static char* mapping[25];
public:
    

    enum TokenType {
        AND = 256,
        BASIC,
        BREAK,
        DO,
        ELSE,
        EQ,
        FALSE,
        GE,
        ID,
        IF,
        INDEX,
        LE,
        MINUS,
        NE,
        NUM,
        OR,
        REAL,
        TEMP,
        TRUE,
        WHILE
    };
    int tag;
    Token(int tag);
    ~Token();
    const char* getTagName();
    std::string toString();
};

class NumToken : public Token {
protected:
public:
    int value;
    NumToken(int val);
};

class Word : Token {
protected:
public:
    std::string lexeme;
    Word(TokenType tag, std::string s);
};

class Lexer {
private:
    std::string m_buffer;
    int m_idx;
    std::map<std::string, Word*> words;
    std::set<Token*> tokens;
    void reserve(Word *w);
public:
    Lexer(const std::string& str);
    ~Lexer();
    Token* scan();
    
};